// This file contains everything specific to changing unit types
var CB;
(function (CB) {
    var Transformation;
    (function (Transformation) {
        var cb = global.craig_brett;
        function change_unit_type(e) {
            /// <summary>Changes the type of the target to the new specified type</summary>
            /// <param name="e">The event object, containing information about the event. </param>
            var source = e.source;
            var target = e.target;
            var skill = e.skill;
            var effect = e.effect;
            var isDeathTransform = !(skill || effect);
            var flags;
            if (skill)
                flags = skill.ScriptFlags;
            else if (effect)
                flags = effect.ScriptFlags;
            else if (isDeathTransform)
                flags = target.ScriptFlags;
            else {
                say("Error: Unknown where the source of transformation is from. Not specified as after skill, effect application or death. ");
                return;
            }
            if (skill && e.success == false)
                return; // for skills, we only transform on successful ones
            var newType = (isDeathTransform) ? flags.get("death_transformation") : flags.get("transform_into");
            // if the unit is already the given type, it could be because the effect has been applied to the new unit
            if (target.IndexedType == newType.replace(/\_/g, " ")) {
                return; // don't do anything if its already the right type
            }
            if (!newType) {
                say("Error: No NewType given to change the unit type.");
                return;
            }
            // now look for specificity, if appropriate
            if (!isDeathTransform && hasUnitSpecificTransform(newType)) {
                // this string has commas in it, so it's probably got specific transforms for given units
                newType = findSpecificTransformType(newType, target.IndexedType);
                // if there's specific transforms, but not for this type and no default one, then don't transform
                if (!newType)
                    return;
            }
            // now we let map creaters randomize things with a /
            // pass in the unit's indexedType as a forbidden value, so it doesn't pick the type it already is
            newType = CB.chooseFromARandomSelectString(newType, "/", [target.IndexedType]);
            var msg = (isDeathTransform) ? flags.get("death_transformation_message") : flags.get("transform_message");
            if (msg) {
                msg = CB.chooseFromARandomSelectString(msg);
                if (isDeathTransform) {
                    say(msg.format(target.GetName(), newType));
                }
                else {
                    say(msg.format(source.GetName(), target.GetName(), newType));
                }
            }
            // Create the unit and modify any shared point values
            var newUnit = shared.CreateUnit(newType);
            if (newUnit == null) {
                say("Error: Unit type {0} not found.".format(newType));
                return;
            }
            // if it's a death transformation, they won't keep the points
            if (!isDeathTransform && flags.get("transform_keeps_points") != false) {
                CB.Utils.applyRelevantPointsFromOldUnitToNew(target, newUnit);
            }
            // so far carrying over items is default
            // put this back in when Allan isn't paying attention :)
            CB.Utils.moveWholeInventoryBetweenUnits(target, newUnit);
            // set the name if one is given, otherwise inherit the former unit's name
            var name = (isDeathTransform) ? flags.get("death_transformation_name") : flags.get("transform_name");
            if (name) {
                newUnit.Name = name;
            }
            else if (target.Name) {
                newUnit.Name = target.Name;
            }
            var team = (isDeathTransform) ? flags.get("death_transformation_team") : flags.get("transform_team");
            if (team) {
                newUnit.Team = team;
            }
            else {
                newUnit.Team = target.Team;
            }
            // Remove the old unit and put the shiny new 1 on the map
            var tile = target.Tile;
            shared.Map.RemoveUnit(target);
            shared.Map.AddUnit(newUnit, tile.X, tile.Y);
            cb.RevertTypes[newUnit.ID] = target;
            if (cb.transports[target.ID]) {
                cb.transports[newUnit.ID] = cb.transports[target.ID];
                cb.transports.Remove(target.ID);
            }
            // transfer all effects from the original unit to the transformed
            // but only if it's not a death transformation
            if (!isDeathTransform)
                newUnit.Effects = target.Effects;
            return newUnit;
        }
        Transformation.change_unit_type = change_unit_type;
        function revert_unit_type(e) {
            /// <summary>Changes a unit back to its original type</summary>
            /// <param name="e">An event object. Stores info on the event</param>
            var target = e.target;
            var skill = e.skill;
            if (skill && e.success == false)
                return; // only revert on successful skills too
            var effect = e.effect;
            var flags;
            if (skill)
                flags = skill.ScriptFlags;
            else if (effect)
                flags = effect.ScriptFlags;
            else {
                say("Error: Source of revert transformation unknown. Should be either skill or effect");
                return;
            }
            if (cb.RevertTypes[target.ID] == null) {
                say("Cannot find previous type of unit, so cannot be reverted from a transformation. ");
                return;
            }
            var revertUnit = cb.RevertTypes[target.ID];
            if (flags.get("transform_keeps_points") != false) {
                CB.Utils.applyRelevantPointsFromOldUnitToNew(target, revertUnit);
            }
            // put the items on this new unit back on the old one
            CB.Utils.moveWholeInventoryBetweenUnits(target, revertUnit);
            // Take away the current unit and put it's reverted version on the map
            var tile = target.Tile;
            shared.Map.RemoveUnit(target);
            shared.Map.AddUnit(revertUnit, tile.X, tile.Y);
            if (cb.transports[target.ID]) {
                cb.transports[revertUnit.ID] = cb.transports[target.ID];
                cb.transports.Remove(target.ID);
            }
            // transfer all effects from the transformed unit to the original
            revertUnit.Effects = target.Effects;
            return revertUnit;
        }
        Transformation.revert_unit_type = revert_unit_type;
        function hasUnitSpecificTransform(transformFlag) {
            // if it's got a bar in the transform list, it's to separate out the available options
            return transformFlag.indexOf('|') != -1;
        }
        function findSpecificTransformType(transformFlag, indexedType) {
            var commaSplits = transformFlag.split(',');
            var firstUnbarredSplit;
            for (var index = 0; index < commaSplits.length; index++) {
                var current = commaSplits[index];
                if (current.indexOf('|') == -1) {
                    if (!firstUnbarredSplit)
                        firstUnbarredSplit = current;
                    continue;
                }
                else {
                    var barSplit = current.split('|');
                    var currentType = barSplit[0];
                    if (currentType == indexedType)
                        return barSplit[1];
                }
            }
            return firstUnbarredSplit;
        }
    })(Transformation = CB.Transformation || (CB.Transformation = {}));
})(CB || (CB = {}));
